﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace THO7AlgoritmTimerApplication
{
    class boundraryBasedInvariants
    {
        public Bitmap FourierDescriptors(Bitmap sourceImage)
        {
            //het lijnen er van maken gaat nog niet helemaal goed. ik denk dat hij niet goed schuin kijkt
            Bitmap returnImage = new Bitmap(sourceImage);
            returnImage = TwoColor(returnImage);
            //return returnImage;
            //returnImage = VerwijderWit(returnImage);
            //returnImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
            //returnImage = VerwijderWit(returnImage);
            //returnImage.RotateFlip(RotateFlipType.Rotate270FlipNone);

            Rectangle rect = new Rectangle(0, 0, returnImage.Width, returnImage.Height);
            BitmapData myBmpData = returnImage.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr = myBmpData.Scan0;
            int numBytes = returnImage.Width * returnImage.Height * 3;
            byte[] rgbValues = new byte[numBytes];
            byte[] newrgbValues = new byte[numBytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, numBytes);

            //vind start positie
            int start = 0;
            for (int i = 0; i < rgbValues.Length; i += 3)
            {
                if (rgbValues[i] == 0)
                {
                    start = i;
                    break;
                }
            }
            //ga nu de buiten kant van het object langs
            int richting = 0;
            for (int i = start; i < rgbValues.Length; )
            {
                int vorige = i;
                newrgbValues[i] = 255;
                
                for (int omliggende = 0; omliggende < 8; omliggende++)
                {
                    try
                    {
                        int volgende = 0;
                        //kijk eerst naast je dan pas schuin
                        switch (omliggende)
                        {
                            case 0: volgende = 3; break;
                            case 1: volgende = returnImage.Width * 3; break;
                            case 2: volgende = -3; break;
                            case 3: volgende = -(returnImage.Width * 3); break;
                            case 4: volgende = -(returnImage.Width * 3) + 3; break;
                            case 5: volgende = (returnImage.Width * 3) + 3; break;
                            case 6: volgende = -(returnImage.Width * 3) - 3; break;
                            case 7: volgende = (returnImage.Width * 3) - 3; break;
                        }
                        if (richting - volgende == 0 || rgbValues[i + volgende] == 255)
                        {
                            continue;
                        }
                        Boolean naastWit = false;
                        for (int wit = 0; wit < 8; wit++)
                        {
                            int t = 0;
                            switch (wit)
                            {
                                case 0: t = 3; break;
                                case 1: t = returnImage.Width * 3; break;
                                case 2: t = -3; break;
                                case 3: t = -(returnImage.Width * 3); break;
                                case 4: t = -(returnImage.Width * 3) + 3; break;
                                case 5: t = (returnImage.Width * 3) + 3; break;
                                case 6: t = -(returnImage.Width * 3) - 3; break;
                                case 7: t = (returnImage.Width * 3) - 3; break;
                            }
                            if (rgbValues[i + volgende + t] == 255)
                            {
                                naastWit = true;
                                i = i+volgende;
                                richting = -volgende;
                                break;
                            }
                        }
                        if (naastWit)
                        {
                            break;
                        }
                    }
                    catch (Exception)
                    {

                    }
                }
                if (i == start || i == vorige)
                {
                    break;
                }
            }

            //je hebt nu de omlijning van het object
            System.Runtime.InteropServices.Marshal.Copy(newrgbValues, 0, ptr, numBytes);
            returnImage.UnlockBits(myBmpData);
            return returnImage;
        }


        private Bitmap TwoColor(Bitmap sourceImage)
        {
            Bitmap returnImage = new Bitmap(sourceImage);
            Rectangle rect = new Rectangle(0, 0, returnImage.Width, returnImage.Height);
            BitmapData myBmpData = returnImage.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr = myBmpData.Scan0;
            int numBytes = returnImage.Width * returnImage.Height * 3;
            byte[] rgbValues = new byte[numBytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, numBytes);
            for (int i = 0; i < rgbValues.Length; i += 3)
            {
                if (rgbValues[i] < 126)
                {
                    rgbValues[i] = 0;
                    rgbValues[i + 1] = 0;
                    rgbValues[i + 2] = 0;
                }
                else
                {
                    rgbValues[i] = 255;
                    rgbValues[i + 1] = 255;
                    rgbValues[i + 2] = 255;
                }
            }
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, numBytes);
            returnImage.UnlockBits(myBmpData);
            return returnImage;
        }
        private Bitmap VerwijderWit(Bitmap sourceImage)
        {
            BitmapData bmpdata = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            IntPtr ptr = bmpdata.Scan0;
            int regellengte = Math.Abs(bmpdata.Stride);
            int bytes = regellengte * sourceImage.Height;
            byte[] rgbValues = new byte[bytes];
            byte[] output = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
            int new_width = 0;
            int new_height = 0;
            for (int regelnummer = 0; regelnummer < sourceImage.Height - 1; regelnummer++)
            {
                for (int convolutie = 0; convolutie < regellengte; convolutie += 3)
                {
                    int pixel = regelnummer * regellengte + convolutie;
                    if (rgbValues[pixel] < 250 || rgbValues[pixel + 1] < 250 || rgbValues[pixel + 2] < 250)
                    {
                        for (int c = 0; c < regellengte; c += 3)
                        {
                            int p = regelnummer * regellengte + c;
                            int new_pixel = new_height * regellengte + c;
                            output[new_pixel] = rgbValues[p];
                            output[new_pixel + 1] = rgbValues[p + 1];
                            output[new_pixel + 2] = rgbValues[p + 2];
                        }
                        new_height++;
                        break;
                    }
                }
            }
            new_width = sourceImage.Width;
            if (new_height == 0)
            {
                new_height = 1;
            }
            Bitmap dest = new Bitmap(new_width, new_height);
            BitmapData bmpdata1 = dest.LockBits(new Rectangle(0, 0, new_width, new_height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            IntPtr ptr1 = bmpdata1.Scan0;
            System.Runtime.InteropServices.Marshal.Copy(output, 0, ptr1, (new_height * regellengte));
            sourceImage.UnlockBits(bmpdata);
            dest.UnlockBits(bmpdata1);
            return dest;
        }
    }
}
